﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using iWare.Wms.Core;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;

namespace iWare.Wms.Application
{
    /// <summary>
    /// 收货列表服务
    /// </summary>
    [Route("api/CollectManagerment")]
    [ApiDescriptionSettings("供应商模块", Name = "CollectManagerment", Order = 110)]

    public class CollectManagermentService : IDynamicApiController, ITransient
    {
        private readonly IRepository<GoodsDelivery, MasterDbContextLocator> _goodsDeliveryRep; //送货单仓储
        private readonly IRepository<GoodsDeliveryDetails, MasterDbContextLocator> _goodsDeliveryDetailsRep; //送货单明细仓储
        private readonly IRepository<PurchaseOrderVsGoodsDelivery, MasterDbContextLocator> _purchaseOrderVsGoodsDeliveryRep; //采购订单与送货单关系仓储
        private readonly IRepository<CollectDelivery, MasterDbContextLocator> _collectDeliveryRep; //收货单仓储
        private readonly IRepository<CollectDeliveryDetails, MasterDbContextLocator> _collectDeliveryDetailsRep; //收货单明细仓储

        #region 默认
        /// <summary>
        /// 默认
        /// </summary>
        /// <param name="goodsDeliveryRep"></param>
        /// <param name="goodsDeliveryDetailsRep"></param>
        /// <param name="purchaseOrderVsGoodsDeliveryRep"></param>
        /// <param name="collectDeliveryRep"></param>
        /// <param name="collectDeliveryDetailsRep"></param>
        public CollectManagermentService(
            IRepository<GoodsDelivery, MasterDbContextLocator> goodsDeliveryRep,
            IRepository<GoodsDeliveryDetails, MasterDbContextLocator> goodsDeliveryDetailsRep,
            IRepository<PurchaseOrderVsGoodsDelivery, MasterDbContextLocator> purchaseOrderVsGoodsDeliveryRep,
            IRepository<CollectDelivery, MasterDbContextLocator> collectDeliveryRep,
            IRepository<CollectDeliveryDetails, MasterDbContextLocator> collectDeliveryDetailsRep
            )
        {
            _goodsDeliveryRep = goodsDeliveryRep;
            _goodsDeliveryDetailsRep = goodsDeliveryDetailsRep;
            _purchaseOrderVsGoodsDeliveryRep = purchaseOrderVsGoodsDeliveryRep;
            _collectDeliveryRep = collectDeliveryRep;
            _collectDeliveryDetailsRep = collectDeliveryDetailsRep;
        }
        #endregion

        /// <summary>
        /// 分页查询已收货列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("CollectPage")]
        public async Task<PageResult<CollectManagermentOutput>> CollectPage([FromQuery] CollectManagermentInput input)
        {
            var account = CurrentUserInfo.Account;

            var deliveryNos = await _goodsDeliveryRep.Where(t => t.SuppCode == account).Select(t => t.DeliveryNo).Distinct().ToListAsync();

            var list = await _collectDeliveryDetailsRep.DetachedEntities
                .Where(u => u.SupplierInfoCode == account)
                .Where(u => deliveryNos.Contains(u.CollectDelivery.DeliveryNo))
                .Where(!string.IsNullOrEmpty(input.DeliveryNo), u => EF.Functions.Like(u.CollectDelivery.DeliveryNo, $"%{input.DeliveryNo.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.ProjectCode), u => EF.Functions.Like(u.ProjectCode, $"%{input.ProjectCode.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.SearchBeginTime), u => u.CreatedTime >= DateTime.Parse(input.SearchBeginTime.Trim()) &&
                 u.CreatedTime <= DateTime.Parse(input.SearchEndTime.Trim()))
                .OrderBy(PageInputOrder.OrderBuilder(input))
                .ProjectToType<CollectManagermentOutput>()
                .ToADPagedListAsync(input.PageNo, input.PageSize);

            foreach (var item in list.Rows)
            {
                var collectDelivery = await _collectDeliveryRep.FirstOrDefaultAsync(z => z.Id == item.CollectDeliveryId);

                var purchaseOrderVsGoodsDelivery = await _purchaseOrderVsGoodsDeliveryRep.DetachedEntities
                    .Where(z => z.GoodsDelivery.DeliveryNo == collectDelivery.DeliveryNo)
                    .ProjectToType<PurchaseOrderVsGoodsDelivery>().FirstOrDefaultAsync();
                item.PurchaseNo = purchaseOrderVsGoodsDelivery == null ? "" : purchaseOrderVsGoodsDelivery.PurchaseOrder.IsJiaJiJian == YesOrNot.Y ? "" : purchaseOrderVsGoodsDelivery.PurchaseOrder.PurchaseNo;
                item.DeliveryNo = item.CollectDelivery.DeliveryNo;
            }

            return list;
        }

        /// <summary>
        /// 分页查询未收货列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("NotCollectPage")]
        public async Task<PageResult<CollectManagermentOutput>> NotCollectPage([FromQuery] CollectManagermentInput input)
        {
            var account = CurrentUserInfo.Account;

            //送货详情信息
            var goodsDeliveryDetails = await _goodsDeliveryDetailsRep.DetachedEntities.Where(t => t.SupplierInfoCode == account)
                .ProjectToType<GoodsDeliveryDetailsOutput>().ToListAsync();

            var deliveryNos = goodsDeliveryDetails.Select(t => t.GoodsDelivery.DeliveryNo).Distinct().ToList();

            //已收货信息
            var collectDeliveryDetailList = await _collectDeliveryDetailsRep.DetachedEntities.Where(z => deliveryNos.Contains(z.CollectDelivery.DeliveryNo))
                .ProjectToType<CollectManagermentOutput>().ToListAsync();

            // 未收货信息
            var notCollectlist = new List<CollectManagermentOutput>();
            foreach (var item in goodsDeliveryDetails)
            {
                var collectDeliveryDetailModel = collectDeliveryDetailList.FirstOrDefault(z => z.CollectDelivery.DeliveryNo == item.GoodsDelivery.DeliveryNo
                && z.ProjectCode == item.ProjectCode && z.Code == item.Code && z.Name == item.Name && z.SpecificationModel == item.SpecificationModel);

                if (collectDeliveryDetailModel == null)
                {
                    var notCollectModel = item.Adapt<CollectManagermentOutput>();
                    notCollectModel.PurchaseNo = item.GoodsDelivery.PurchaseNo;
                    notCollectModel.DeliveryNo = item.GoodsDelivery.DeliveryNo;
                    notCollectModel.BrandName = item.BrandName;
                    notCollectModel.CollectQuantity = item.DeliveryQuantity;
                    notCollectModel.CreatedTime = null;
                    notCollectlist.Add(notCollectModel);
                }
                else
                {
                    if (collectDeliveryDetailModel.CollectQuantity < item.DeliveryQuantity)
                    {
                        var notCollectModel = item.Adapt<CollectManagermentOutput>();
                        notCollectModel.PurchaseNo = item.GoodsDelivery.PurchaseNo;
                        notCollectModel.DeliveryNo = item.GoodsDelivery.DeliveryNo;
                        notCollectModel.BrandName = item.BrandName;
                        notCollectModel.CollectQuantity = item.DeliveryQuantity - collectDeliveryDetailModel.CollectQuantity;
                        notCollectModel.CreatedTime = null;
                        notCollectlist.Add(notCollectModel);
                    }
                }
            }

            return notCollectlist.Where(!string.IsNullOrEmpty(input.DeliveryNo), z => z.DeliveryNo == input.DeliveryNo)
                .Where(!string.IsNullOrEmpty(input.ProjectCode), z => z.ProjectCode == input.ProjectCode)
                .ToADPagedList(input.PageNo, input.PageSize);
        }
    }
}
